const { verifyToken, extractTokenFromHeader } = require('../utils/auth');
const { unauthorized, forbidden } = require('../utils/response');
const userDao = require('../dao/userDao');

/**
 * JWT认证中间件
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 * @param {Function} next - Next middleware function
 */
const authenticateToken = async (req, res, next) => {
  try {
    const token = extractTokenFromHeader(req);

    if (!token) {
      return unauthorized(res, '访问令牌缺失');
    }

    const decoded = verifyToken(token);

    // 验证用户是否存在且状态正常
    const user = await userDao.findById(decoded.id);
    if (!user || user.status !== 'active') {
      return unauthorized(res, '用户不存在或已被禁用');
    }

    req.user = decoded;
    req.userInfo = user;
    next();
  } catch (error) {
    if (error.name === 'TokenExpiredError') {
      return unauthorized(res, '访问令牌已过期');
    } else if (error.name === 'JsonWebTokenError') {
      return unauthorized(res, '无效的访问令牌');
    } else {
      return unauthorized(res, '令牌验证失败');
    }
  }
};

/**
 * 可选认证中间件（不强制要求认证）
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 * @param {Function} next - Next middleware function
 */
const optionalAuth = (req, res, next) => {
  try {
    const token = extractTokenFromHeader(req);
    
    if (token) {
      const decoded = verifyToken(token);
      req.user = decoded;
    }
    
    next();
  } catch (error) {
    // 可选认证失败时不返回错误，继续执行
    next();
  }
};

/**
 * 角色验证中间件
 * @param {Array} allowedRoles - 允许的角色列表
 * @returns {Function} 中间件函数
 */
const requireRoles = (allowedRoles) => {
  return (req, res, next) => {
    if (!req.user) {
      return unauthorized(res, '需要认证');
    }

    if (!allowedRoles.includes(req.user.role)) {
      return res.status(403).json({
        code: 403,
        message: '权限不足',
        timestamp: Date.now()
      });
    }

    next();
  };
};

/**
 * 管理员权限验证中间件
 */
const requireAdmin = requireRoles(['admin']);

/**
 * 教师权限验证中间件
 */
const requireTeacher = requireRoles(['admin', 'teacher']);

/**
 * 检查是否为资源所有者或管理员
 * @param {string} userIdField - 请求参数中用户ID字段名
 */
const requireOwnerOrAdmin = (userIdField = 'userId') => {
  return (req, res, next) => {
    if (!req.user) {
      return unauthorized(res, '用户未认证');
    }

    const userRole = req.userInfo?.role || req.user.role || 'user';
    const resourceUserId = req.params[userIdField] || req.body[userIdField];

    // 管理员可以访问所有资源
    if (userRole === 'admin') {
      return next();
    }

    // 用户只能访问自己的资源
    if (req.user.id.toString() === resourceUserId?.toString()) {
      return next();
    }

    return forbidden(res, '只能访问自己的资源');
  };
};

/**
 * 检查用户是否为自己
 */
const requireSelf = requireOwnerOrAdmin('id');

module.exports = {
  authenticateToken,
  optionalAuth,
  requireRoles,
  requireAdmin,
  requireTeacher,
  requireOwnerOrAdmin,
  requireSelf
};
